package com.innovation.ic.b1b.monitor.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.innovation.ic.b1b.monitor.base.handler.ApiAvailableJobHandler;
import com.innovation.ic.b1b.monitor.base.mapper.ApiAvailableJobMapper;
import com.innovation.ic.b1b.monitor.base.model.Api;
import com.innovation.ic.b1b.monitor.base.model.ApiAvailableJob;
import com.innovation.ic.b1b.monitor.base.pojo.constant.JobDataMapConstant;
import com.innovation.ic.b1b.monitor.base.pojo.constant.TableNameConstant;
import com.innovation.ic.b1b.monitor.base.pojo.enums.EnableEnum;
import com.innovation.ic.b1b.monitor.base.pojo.variable.ServiceResult;
import com.innovation.ic.b1b.monitor.base.pojo.variable.apiAvailableJob.ApiAvailableJobDataPojo;
import com.innovation.ic.b1b.monitor.base.service.masterSlave.ApiAvailableJobService;
import com.innovation.ic.b1b.monitor.base.service.masterSlave.ServiceHelper;
import com.innovation.ic.b1b.monitor.base.vo.apiAvailableJob.ApiAvailableJobAddVo;
import com.innovation.ic.b1b.monitor.base.vo.apiAvailableJob.ApiAvailableJobListQueryVo;
import com.innovation.ic.b1b.monitor.base.vo.apiAvailableJob.ApiAvailableJobUpdateVo;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author zengqinglong
 * @desc 接口可用任务管理
 * @Date 2023/3/30 10:39
 **/
@Service
@Slf4j
public class ApiAvailableJobServiceImpl extends ServiceImpl<ApiAvailableJobMapper, ApiAvailableJob> implements ApiAvailableJobService {
    @Resource
    private ServiceHelper serviceHelper;

    /**
     * 新增任务
     *
     * @param apiAvailableJobAddVo
     * @return
     */
    @Override
    public ServiceResult<Boolean> add(ApiAvailableJobAddVo apiAvailableJobAddVo) {
        boolean result = Boolean.FALSE;
        String message;
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(result);

        LambdaQueryWrapper<ApiAvailableJob> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApiAvailableJob::getApiId, apiAvailableJobAddVo.getApiId());
        Integer selectCount = serviceHelper.getApiAvailableJobMapper().selectCount(queryWrapper);
        if (selectCount > 0) {
            serviceResult.setMessage("当前接口可用任务已存在，请勿重复添加");
            return serviceResult;
        }

        // 校验apiId是否存在
        Api api = serviceHelper.getApiMapper().selectById(apiAvailableJobAddVo.getApiId());
        if (api != null) {
            ApiAvailableJob apiAvailableJob = new ApiAvailableJob();
            BeanUtils.copyProperties(apiAvailableJobAddVo, apiAvailableJob);
            if (apiAvailableJobAddVo.getEnable() == null) {
                apiAvailableJob.setEnable(EnableEnum.NO.getCode());
            }
            apiAvailableJob.setCreateTime(new Date(System.currentTimeMillis()));
            int insert = serviceHelper.getApiAvailableJobMapper().insert(apiAvailableJob);
            if (insert > 0) {
                message = ServiceResult.INSERT_SUCCESS;
                result = Boolean.TRUE;

                String jobId = TableNameConstant.API_AVAILABLE_JOB + "_" + apiAvailableJob.getId();

                // 组装任务参数
                JobDataMap jobDataMap = new JobDataMap();
                jobDataMap.put(JobDataMapConstant.ID, apiAvailableJob.getId());

                serviceHelper.getQuartzManager().createScheduleJob(jobId, ApiAvailableJobHandler.class.getName(), "ApiAvailableJobHandler", jobDataMap, apiAvailableJob.getScheduleExpression());
            } else {
                message = ServiceResult.INSERT_FAIL;
            }
        } else {
            message = "接口信息不存在，请配置接口信息后重新添加接口监控任务";
        }

        serviceResult.setResult(result);
        serviceResult.setMessage(message);
        return serviceResult;
    }

    /**
     * 根据条件获取 接口任务列表
     *
     * @param apiAvailableJobListQueryVo
     * @return
     */
    @Override
    public ServiceResult<PageInfo<ApiAvailableJobDataPojo>> queryList(ApiAvailableJobListQueryVo apiAvailableJobListQueryVo, Boolean isMain) {
        PageHelper.startPage(apiAvailableJobListQueryVo.getPageNo(), apiAvailableJobListQueryVo.getPageSize());
        // 查询接口监控任务列表数据
        List<ApiAvailableJobDataPojo> data = serviceHelper.getApiAvailableJobMapper().queryList(apiAvailableJobListQueryVo);
        PageInfo<ApiAvailableJobDataPojo> pageInfo = new PageInfo<>(data);
        return ServiceResult.ok(pageInfo, ServiceResult.SELECT_SUCCESS);
    }

    /**
     * 根据id 删除接口监控任务
     *
     * @param id
     * @return
     */
    @Override
    public ServiceResult<Boolean> delete(Integer id) {
        boolean result = Boolean.FALSE;
        String message = ServiceResult.DELETE_FAIL;

        int i = serviceHelper.getApiAvailableJobMapper().deleteById(id);
        if (i > 0) {
            log.info("删除接口监控任务 : 已删除id为[{}]mysql监控任务", id);
            result = Boolean.TRUE;
            message = ServiceResult.DELETE_SUCCESS;
        } else {
            log.info("删除接口监控任务 : 删除id为[{}]mysql监控任务失败，数据不存在", id);
        }

        return ServiceResult.ok(result, message);
    }

    /**
     * 根据id 查询接口监控任务详情
     *
     * @param id
     * @return
     */
    @Override
    public ServiceResult<ApiAvailableJobDataPojo> info(Integer id, Boolean isMian) {
        ApiAvailableJobDataPojo result = serviceHelper.getApiAvailableJobMapper().info(id);
        return ServiceResult.ok(result, ServiceResult.SELECT_SUCCESS);
    }

    /**
     * 根据id 更新接口监控任务
     *
     * @param availableJobUpdateVo
     * @return
     */
    @Override
    public ServiceResult<Boolean> update(ApiAvailableJobUpdateVo availableJobUpdateVo) {
        boolean result = Boolean.FALSE;
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(result);

        LambdaQueryWrapper<ApiAvailableJob> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApiAvailableJob::getApiId, availableJobUpdateVo.getApiId());
        queryWrapper.ne(ApiAvailableJob::getId, availableJobUpdateVo.getId());
        Integer selectCount = serviceHelper.getApiAvailableJobMapper().selectCount(queryWrapper);
        if (selectCount > 0) {
            serviceResult.setMessage("更新接口监控任务 : 当前接口可用任务已存在，请勿重复修改重复的接口");
            return serviceResult;
        }

        //  校验apiId是否存在
        Api api = serviceHelper.getApiMapper().selectById(availableJobUpdateVo.getApiId());
        if (api != null) {
            ApiAvailableJob apiAvailableJob = new ApiAvailableJob();
            BeanUtils.copyProperties(availableJobUpdateVo, apiAvailableJob);
            int i = serviceHelper.getApiAvailableJobMapper().updateById(apiAvailableJob);
            if (i > 0) {
                log.info("更新接口监控任务 : 更新id为[{}]接口监控任务成功", apiAvailableJob.getId());
                return ServiceResult.ok(Boolean.TRUE, ServiceResult.UPDATE_SUCCESS);
            } else {
                log.info("更新接口监控任务 : 更新id为[{}]接口监控任务失败", apiAvailableJob.getId());
                return ServiceResult.ok(Boolean.FALSE, ServiceResult.UPDATE_FAIL);
            }
        } else {
            log.info("更新接口监控任务 : apiId=[{}]的信息不存在", availableJobUpdateVo.getApiId());
            return ServiceResult.error(ServiceResult.UPDATE_FAIL);
        }
    }

    /**
     * 根据id 执行接口监控任务
     *
     * @param id
     * @return
     */
    @Override
    public ServiceResult<Boolean> executeJob(Integer id) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();

        try {
            String jobId = TableNameConstant.API_AVAILABLE_JOB + "_" + id;
            serviceHelper.getQuartzManager().runOnce(jobId);
        } catch (Exception e) {
            serviceResult.setMessage(ServiceResult.OPERATE_FAIL);
            serviceResult.setResult(Boolean.FALSE);
            serviceResult.setSuccess(Boolean.FALSE);
            return serviceResult;
        }

        serviceResult.setMessage(ServiceResult.OPERATE_SUCCESS);
        serviceResult.setResult(Boolean.TRUE);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }


}
